import * as THREE from 'three';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import {GUI} from 'three/examples/jsm/libs/dat.gui.module.js';

import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader.js';
import {EffectComposer} from 'three/examples/jsm/postprocessing/EffectComposer.js';
import {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass.js';
// import {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass.js';// 自定义了后期
import {OutlinePass} from 'three/examples/jsm/postprocessing/OutlinePass.js';
// import {FXAAShader} from 'three/examples/jsm/shaders/FXAAShader.js'; // 抗锯齿插件

import '../../css/base.css'

let container, stats;
let camera, scene, renderer, controls;
let raycaster = new THREE.Raycaster();

let mouse = new THREE.Vector2();
let selectedObjects = [];

let composer, effectFXAA, outlinePass;
let obj3d = new THREE.Object3D();

let group = new THREE.Group();

let params = {
  edgeStrength: 3.0,
  edgeGlow: 0.0,
  edgeThickness: 1.0,
  pulsePeriod: 0,
  rotate: false,
  usePatternTexture: false
}; // 参数

function initBase() {
  container = document.createElement('div');
  document.body.appendChild(container);

  let width = window.innerWidth;
  let height = window.innerHeight;

  renderer = new THREE.WebGLRenderer();
  renderer.shadowMap.enabled = true;
  renderer.setSize(width, height);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100);
  camera.position.set(0, 0, 8);
} // 初始化三大基础
function initControls() {
  controls = new OrbitControls(camera, renderer.domElement);
  controls.minDistance = 5;
  controls.maxDistance = 20;
  controls.enablePan = false;
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
} // 初始化控制器
function initLight() {
  scene.add(new THREE.AmbientLight(0xaaaaaa, 0.2));

  let light = new THREE.DirectionalLight(0xddffdd, 0.6);
  light.position.set(1, 1, 1);

  light.castShadow = true;

  light.shadow.mapSize.width = 1024;
  light.shadow.mapSize.height = 1024;

  let d = 10;

  light.shadow.camera.left = -d;
  light.shadow.camera.right = d;
  light.shadow.camera.top = d;
  light.shadow.camera.bottom = -d;

  light.shadow.camera.far = 1000;

  scene.add(light);
}// 初始化灯光
function initModel() {
  let manager = new THREE.LoadingManager();
  manager.onProgress = function (item, loaded, total) {
    console.log(item, loaded, total);
  };
  // let loader = new OBJLoader(manager);
  // loader.load('three/examples/models/obj/tree.obj', function (object) {
  //     let scale = 1.0;
  //     object.traverse(function (child) {
  //
  //         if (child instanceof THREE.Mesh) {
  //
  //             child.geometry.center();
  //             child.geometry.computeBoundingSphere();
  //             scale = 0.2 * child.geometry.boundingSphere.radius;
  //
  //             let phongMaterial = new THREE.MeshPhongMaterial({
  //                 color: 0xffffff,
  //                 specular: 0x111111,
  //                 shininess: 5
  //             });
  //             child.material = phongMaterial;
  //             child.receiveShadow = true;
  //             child.castShadow = true;
  //
  //         }
  //
  //     });
  //
  //     object.position.y = 1;
  //     object.scale.divideScalar(scale);
  //     obj3d.add(object);
  // });
  // 生成球
  let geometry = new THREE.SphereBufferGeometry(3, 48, 24);
  for (let i = 0; i < 20; i++) {
    let material = new THREE.MeshLambertMaterial();
    material.color.setHSL(Math.random(), 1.0, 0.3);

    let mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = Math.random() * 4 - 2;
    mesh.position.y = Math.random() * 4 - 2;
    mesh.position.z = Math.random() * 4 - 2;
    mesh.receiveShadow = true;
    mesh.castShadow = true;
    mesh.scale.multiplyScalar(Math.random() * 0.3 + 0.1);
    group.add(mesh);
  }

  let floorMaterial = new THREE.MeshLambertMaterial({side: THREE.DoubleSide});

  let floorGeometry = new THREE.PlaneBufferGeometry(12, 12);
  let floorMesh = new THREE.Mesh(floorGeometry, floorMaterial);
  floorMesh.rotation.x -= Math.PI * 0.5;
  floorMesh.position.y -= 1.5;
  group.add(floorMesh);
  floorMesh.receiveShadow = true;

  let geometry2 = new THREE.TorusBufferGeometry(1, 0.3, 16, 100);
  let material = new THREE.MeshPhongMaterial({color: 0xffaaff});
  let torus = new THREE.Mesh(geometry2, material);
  torus.position.z = -4;
  group.add(torus);
  torus.receiveShadow = true;
  torus.castShadow = true;

  scene.add(group);
  group.add(obj3d);
  console.log('scene: ', scene);
  {
    let geometry3 = new THREE.BoxBufferGeometry(1, 1, 1);
    let material3 = new THREE.MeshBasicMaterial({color: 0x00ff00});
    let cube = new THREE.Mesh(geometry3, material3);
    cube.name = 'cube'
    scene.add(cube);
  }
} // 初始化模型
function initHelper() {
  stats = new Stats();
  container.appendChild(stats.dom);

  function gui() {
    let gui = new GUI({width: 300});
    gui.add(params, 'edgeStrength', 0.01, 10).onChange(function (value) {
      outlinePass.edgeStrength = Number(value);
    });
    gui.add(params, 'edgeGlow', 0.0, 1).onChange(function (value) {
      outlinePass.edgeGlow = Number(value);
    });
    gui.add(params, 'edgeThickness', 1, 4).onChange(function (value) {
      outlinePass.edgeThickness = Number(value);
    });
    gui.add(params, 'pulsePeriod', 0.0, 5).onChange(function (value) {
      outlinePass.pulsePeriod = Number(value);
    });
    gui.add(params, 'rotate');
    gui.add(params, 'usePatternTexture').onChange(function (value) {
      outlinePass.usePatternTexture = value;
    });
    let Configuration = function () {
      this.visibleEdgeColor = '#ffffff';
      this.hiddenEdgeColor = '#190a05';
    };
    let conf = new Configuration();
    gui.addColor(conf, 'visibleEdgeColor').onChange(function (value) {
      outlinePass.visibleEdgeColor.set(value);
    });
    gui.addColor(conf, 'hiddenEdgeColor').onChange(function (value) {
      outlinePass.hiddenEdgeColor.set(value);
    });
  } // gui
  gui();
} // 初始化帮手
function initPostprocessing() {
  composer = new EffectComposer(renderer);

  let renderPass = new RenderPass(scene, camera);
  composer.addPass(renderPass);

  outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
  composer.addPass(outlinePass);

  let onLoad = function (texture) {
    outlinePass.patternTexture = texture;
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
  };

  let loader = new THREE.TextureLoader();

  // loader.load('three/examples/textures/tri_pattern.jpg', onLoad);

  // effectFXAA = new ShaderPass(FXAAShader); // 自定义了后期
  // effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
  // composer.addPass(effectFXAA);

  window.addEventListener('mousemove', onTouchMove);
  window.addEventListener('touchmove', onTouchMove);

  function onTouchMove(event) {
    let x, y;
    if (event.changedTouches) {
      x = event.changedTouches[0].pageX;
      y = event.changedTouches[0].pageY;
    } else {
      x = event.clientX;
      y = event.clientY;
    }
    mouse.x = (x / window.innerWidth) * 2 - 1;
    mouse.y = -(y / window.innerHeight) * 2 + 1;
    checkIntersection();
  }

  function addSelectedObject(object) {
    selectedObjects = [];
    selectedObjects.push(object);
  }

  function checkIntersection() {
    raycaster.setFromCamera(mouse, camera);
    let intersects = raycaster.intersectObjects([scene], true);
    if (intersects.length > 0) {
      let selectedObject = intersects[0].object;
      addSelectedObject(selectedObject);
      outlinePass.selectedObjects = selectedObjects;
    } else {
      outlinePass.selectedObjects = [];
    }
  }
} //postprocessing 初始化后期处理
function onWindowResize() {
  let width = window.innerWidth;
  let height = window.innerHeight;
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
  composer.setSize(width, height);
  // effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
} // 控制窗口大小
function render() {
  let timer = performance.now();
  if (params.rotate) {
    group.rotation.y = timer * 0.0001;
  }
  controls.update();
  composer.render();
} // 加载器

function animate() {
  requestAnimationFrame(animate);
  render()
  stats.update();
}// 动画
(function () {
  initBase();
  initControls();
  initPostprocessing();
  initLight();
  initModel();
  initHelper()
  window.addEventListener('resize', onWindowResize, false);
  animate();
})()// 启动
